import { debounce } from './utils/index.js'

const SIZE = 15
let W
let SL
let moveSteps = 0
let isBlack = true
let chess = Array.from({ length: SIZE }, () => Array(SIZE).fill(-1))

W = Math.min(window.innerWidth, window.innerHeight) / (SIZE + 3)
SL = W * (SIZE + 1)

let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')

canvas.width = canvas.height = SL
canvas.style.cssText = 'position: absolute; inset: 0; margin: auto;'
document.body.appendChild(canvas)

canvas.onclick = e => {
  const [x, y] = [e.offsetX, e.offsetY].map(v => Math.round(v / W) - 1)
  if (chess[x][y] !== -1) return

  moveSteps++
  drawPiece(x, y, isBlack)
  // 黑棋： 1；白棋： 0；空：-1
  chess[x][y] = isBlack ? 1 : 0

  let message = ''

  isWin(x, y, chess[x][y], chess) &&
    (message = `${isBlack ? '黑' : '白'}棋胜！`)

  moveSteps === SIZE ** 2 && (message = '平局！')

  if (message) {
    setTimeout(() => {
      alert(message)
    }, 0)
    canvas.onclick = e => e.preventDefault()
    return
  }

  isBlack = !isBlack
}

const isWin = (x, y, role, chess) => {
  for (let [dx, dy] of [
    [1, 0],
    [0, 1],
    [1, 1],
    [1, -1]
  ]) {
    let [count, i, j] = [1, 0, 0]
    while (count < 5 && chess[x + dx * ++i]?.[y + dy * i] === role) count++
    while (count < 5 && chess[x - dx * ++j]?.[y - dy * j] === role) count++
    if (count === 5) {
      i = 4 - j
      drawLine(x + dx * i, y + dy * i, x - dx * j, y - dy * j, 2, 'red')
      return true
    }
  }
  return false
}

const drawPiece = (x, y, isBlack) => {
  x = (x + 1) * W
  y = (y + 1) * W

  ctx.save()
  ctx.beginPath()
  ctx.arc(x, y, W / 2.5, 0, 2 * Math.PI)
  ctx.closePath()

  ctx.shadowColor = 'rgba(0,0,0, .5)'
  ctx.shadowOffsetX = ctx.shadowOffsetY = W * 0.06
  ctx.shadowBlur = W * 0.04
  const gradient = ctx.createRadialGradient(x, y, 0, x, y, W * 0.4)
  gradient.addColorStop(0, isBlack ? '#707070' : '#FFFFFF')
  gradient.addColorStop(1, isBlack ? '#000000' : '#D5D8DC')

  ctx.fillStyle = gradient
  ctx.fill()
  ctx.restore()
}

const drawBoard = () => {
  ctx.fillStyle = '#E4A751'
  ctx.fillRect(0, 0, SL, SL)
  let i = 0
  while (i < SIZE) {
    drawLine(0, i, SIZE - 1, i)
    drawLine(i, 0, i, SIZE - 1)
    i++
  }
}

const drawLine = (x, y, dx, dy, lineWidth = 1, lineColor = 'black') => {
  ctx.lineWidth = lineWidth
  ctx.strokeStyle = lineColor

  ctx.beginPath()
  ctx.moveTo((x + 1) * W, (y + 1) * W)
  ctx.lineTo((dx + 1) * W, (dy + 1) * W)
  ctx.closePath()
  ctx.stroke()
}

const flushBoard = () => {
  ctx.clearRect(0, 0, SL, SL)
  W = Math.min(window.innerWidth, window.innerHeight) / (SIZE + 3)
  SL = W * (SIZE + 1)
  canvas.width = canvas.height = SL
  drawBoard()
}

const handleResize = () => {
  flushBoard()

  chess.forEach((row, x) => {
    row.forEach((role, y) => {
      if (role !== -1) drawPiece(x, y, role)
    })
  })
}

window.onresize = debounce(handleResize)

window.onload = drawBoard
